using Firestarter.DB.Schema.BO;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using UIForm=Habanero.BO.ClassDefinition.UIForm;

namespace Firestarter.DB.Schema.UI
{
    public class ChooseObjectTypesWizardStep : WizardStepWin
    {
        private IPanelInfo _reverseEngineeringSettingsPanelInfo;
        private ReverseEngineering _reverseEngineering;
        private SingleRelationship<ReverseEngineeringSettings> _reverseEngineeringSettingsRelationship;

        public ChooseObjectTypesWizardStep()
        {
            IControlFactory factory = GlobalUIRegistry.ControlFactory;
            PanelBuilder panelBuilder = new PanelBuilder(factory);

            IPanel databaseConnectionPanel = SetupDatabaseConnectionPanel(panelBuilder);
            IGroupBox groupBox = factory.CreateGroupBox("Database Connection");
            BorderLayoutManager groupBoxLayoutManager = factory.CreateBorderLayoutManager(groupBox);
            groupBoxLayoutManager.AddControl(databaseConnectionPanel, BorderLayoutManager.Position.Centre);

            BorderLayoutManager layoutManager = factory.CreateBorderLayoutManager(this);
            layoutManager.AddControl(groupBox, BorderLayoutManager.Position.Centre);
        }

        private IPanel SetupDatabaseConnectionPanel(PanelBuilder panelBuilder)
        {
            _reverseEngineeringSettingsPanelInfo = panelBuilder.BuildPanelForForm(GetReverseEngineeringSettingsUIForm());
            _reverseEngineeringSettingsPanelInfo.BusinessObject = new ReverseEngineeringSettings();
            IPanel panel = _reverseEngineeringSettingsPanelInfo.Panel;
            //PanelInfo.Field fieldInfo = _reverseEngineeringSettingsPanelInfo.FieldInfos[_reverseEngineeringSettingsPanelInfo.FieldInfos.Count - 1];
            //panel.Height = fieldInfo.InputControl.Bottom + 5;
            return panel;
        }

        private static IUIForm GetReverseEngineeringSettingsUIForm()
        {
            return ClassDef.Get<ReverseEngineeringSettings>().GetUIDef("default").UIForm;
        }

        public ReverseEngineering ReverseEngineering
        {
            get { return _reverseEngineering; }
            set {
                if (_reverseEngineeringSettingsRelationship != null)
                {
                    _reverseEngineeringSettingsRelationship.Updated -= ReverseEngineeringSettings_Changed;
                }
                _reverseEngineering = value;
                if (_reverseEngineering != null)
                {
                    _reverseEngineeringSettingsRelationship = _reverseEngineering
                        .Relationships.GetSingle<ReverseEngineeringSettings>("ReverseEngineeringSettings");
                    _reverseEngineeringSettingsRelationship.Updated += ReverseEngineeringSettings_Changed;
                }
                UpdateReverseEngineeringSettings();
            }
        }

        private void ReverseEngineeringSettings_Changed(object sender, BOEventArgs<ReverseEngineeringSettings> e)
        {
            UpdateReverseEngineeringSettings();
        }

        private void UpdateReverseEngineeringSettings()
        {
            ReverseEngineeringSettings reverseEngineeringSettings = null;
            if (_reverseEngineering != null)
                reverseEngineeringSettings = _reverseEngineering.ReverseEngineeringSettings as ReverseEngineeringSettings;
            _reverseEngineeringSettingsPanelInfo.BusinessObject = reverseEngineeringSettings;
        }

        public ReverseEngineeringSettings ReverseEngineeringSettings
        {
            get { return (ReverseEngineeringSettings)_reverseEngineeringSettingsPanelInfo.BusinessObject; }
        }

        public IPanelInfo ReverseEngineeringSettingsPanelInfo
        {
            get { return _reverseEngineeringSettingsPanelInfo; }
        }

        #region Implementation of IWizardStep

        /// <summary>
        ///             Initialises the step. Run when the step is reached.
        /// </summary>
        public override void InitialiseStep()
        {
            
        }

        /// <summary>
        ///             Verifies whether this step can be passed.
        /// </summary>
        /// <param name="message">Error message should moving on be disallowed. This message will be displayed to the user by the WizardControl.</param>
        public override bool CanMoveOn(out string message)
        {
            //TODO Mark 20 Jan 2009 : Are there any cases when you wouldn't move on? (-Nothing selected to import)
            message = null;
            return true;
        }

        /// <summary>
        ///             Verifies whether the user can move back from this step.
        /// </summary>
        public override bool CanMoveBack()
        {
            return true;
        }

        /// <summary>
        ///             Provides an interface for the developer to implement functionality to cancel any edits made as part of this
        ///             wizard step. The default wizard controller functionality is to call all wizard steps cancelStep methods when
        ///             its Cancel method is called.
        /// </summary>
        public override void CancelStep()
        {
            if (_reverseEngineering == null) return;
            if (_reverseEngineering.ReverseEngineeringSettings == null) return;
            _reverseEngineering.ReverseEngineeringSettings.CancelEdits();
        }

        /// <summary>
        ///             The text that you want displayed at the top of the wizard control when this step is active.
        /// </summary>
        public override string HeaderText
        {
            get { return "Filter the database object set to reverse engineer."; }
        }

        #endregion
    }
}
